import { _decorator, Component, Node, easing } from 'cc';
import { BaseView } from '../../../scripts/libs/rxjs/cc3/BaseView';
import { ReactiveProperty } from '../../../scripts/libs/rxjs/cc3/ReactiveProperty';
import { Quat } from 'cc';
import { Stage3dView } from './Stage3dView';
import { quat } from 'cc';
import { Vec3 } from 'cc';
import { v3 } from 'cc';
import { TweenToStart } from '../../../scripts/libs/rxjs/cc3/TweenStart';
import { EveryFrameScene } from '../../../scripts/libs/rxjs/cc3/CreatorSchedule';
const { ccclass, property } = _decorator;

const _q0 = quat();
const _q1 = quat();
const _q2 = quat();
const _q3 = quat();

const _v30 = v3();

@ccclass('Block')
export class Block extends BaseView {

    stage3dView: Stage3dView;

    blockId = ReactiveProperty.Create<number>(null);

    posId = ReactiveProperty.Create<number>(null);

    valid = ReactiveProperty.Create<boolean>(null);

    reset() {
        this.blockId.value = null;
        this.node.setRotation(Quat.IDENTITY);
        this.nextRollDirection.value = null;
        this.rolling.value = false;
        this.dropping.value = false;
    }

    recycle() {
        this.reset();
    }

    rolling = ReactiveProperty.Create(false);
    nextRollDirection = ReactiveProperty.Create<number>(null);
    roll(direction: number, callback?: () => void) {
        this.rolling.value = true;
        let half = this.stage3dView.blockDefaultY;
        let v0 = this.stage3dView.getPositionByIdx(this.posId.value); // 脚底中心
        let v1 = v3(v0.x, v0.y + half, v0.z); // 质心
        this.node.getRotation(_q0); // 当前的旋转状态
        let o: Vec3 = null; // 旋转中心
        if (direction == 0) {
            o = v3(half, 0, 0);
            Quat.fromAxisAngle(_q1, Vec3.UNIT_Z, -90 * Math.PI / 180);
        } else if (direction == 1) {
            o = v3(0, 0, -half)
            Quat.fromAxisAngle(_q1, Vec3.UNIT_X, -90 * Math.PI / 180);
        } else if (direction == 2) {
            o = v3(-half, 0, 0);
            Quat.fromAxisAngle(_q1, Vec3.UNIT_Z, 90 * Math.PI / 180);
        } else if (direction == 3) {
            o = v3(0, 0, half);
            Quat.fromAxisAngle(_q1, Vec3.UNIT_X, 90 * Math.PI / 180);
        }
        o.add(v0);
        v1.subtract(o); // v1为旋转中心指向质心的向量
        let v2 = v3();
        Vec3.transformQuat(v2, v1, _q1);
        this.node.clearSubscriptions();
        EveryFrameScene(.2, this.node).subscribe({
            next: _ => {
                _ = easing.sineIn(_);
                let _v3 = v3();
                Vec3.slerp(_v3, v1, v2, _);
                let _v4 = v3(o).add(_v3);
                this.node.setPosition(_v4);
                Quat.multiply(_q2, _q1, _q0); // _q2为终点旋转状态
                Quat.slerp(_q3, _q0, _q2, _);
                this.node.setRotation(_q3);
            },
            complete: () => {
                this.rolling.value = false;
                if (callback) callback();
            }
        }).addTo(this.node);
    }

    dropping = ReactiveProperty.Create(false);
    drop(callback?: () => void) {
        this.dropping.value = true;
        this.node.clearSubscriptions();
        EveryFrameScene(.2, this.node).subscribe({
            next: _ => {
                _ = easing.quadIn(_);
                let oriPos = this.node.getPosition();
                let targetPos = v3(oriPos).add(v3(0, -10, 0));

                Vec3.lerp(_v30, oriPos, targetPos, _);
                this.node.setPosition(_v30);
            },
            complete: () => {
                this.dropping.value = false;
                if (callback) callback();
            }
        });
    }

}

